package cn.com.cnxfs.myzjsu;

import android.Manifest;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.CookieManager;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;

import org.json.JSONObject;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {
    private final int VERSION = 4; //APP版本
    private WebView webView = null;
    private final String url_index = "https://myapp.zjgsu.edu.cn/home/index?type=WeiXinGzhClient";
    private final String url_update = "https://cnxfs.com.cn/myZJSU/check.txt";
    private SharedPreferences sharedPreferences;
    private final String[] permissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private ValueCallback<Uri> uploadFile;
    private ValueCallback<Uri[]> uploadFiles;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sharedPreferences = getSharedPreferences("settings", MODE_PRIVATE);
        webView = findViewById(R.id.web);
        final WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setDomStorageEnabled(true);
        settings.setDefaultTextEncodingName("UTF-8");
        settings.setAllowContentAccess(true);
        settings.setAllowFileAccess(true);
        settings.setMediaPlaybackRequiresUserGesture(true);
        settings.setCacheMode(WebSettings.LOAD_NO_CACHE); //不使用缓存
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                Log.d("当前url", url);
                super.onPageFinished(view, url);
                CookieManager.getInstance().flush(); //更新cookie
                if(url.startsWith("https://uia.zjgsu.edu.cn/cas/login")) {
                    Log.d("URL拦截", "出现登录页面！");
                    webView.post(() -> {
                        final String strJS = "javascript:$('#username').val('"
                                + sharedPreferences.getString("username","")
                                +"');$('#ppassword').val('"
                                +sharedPreferences.getString("password","")
                                +"');document.getElementById('dl').click();";
                        webView.evaluateJavascript(strJS, null);
                    });
                }else if(url.startsWith("https://myapp.zjgsu.edu.cn/")){
                    Log.d("URL拦截", "修复导航栏！");
                    webView.post(() -> {
                        final String strJS = "javascript:document.getElementById('app').firstElementChild.style='padding-bottom: 53px';";
                        webView.evaluateJavascript(strJS,null);
                    });
                }else if(url.equals("https://ticket.zjgsu.edu.cn/stucheckservice/auth/login/stuCheck")){
                    Log.d("URL拦截", "进入晚打卡页面！索要定位权限");
                    if(!checkPermission())
                        ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);
                }
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                final String url = request.getUrl().toString();
                //Log.d("页面跳转", "准备至:"+url);
                try{
                    if(url.startsWith("alipays://")){ //跳转到支付宝
                        startActivity(new Intent(Intent.ACTION_VIEW, request.getUrl()));
                        return true;
                    }
                }catch (Exception e){ //防止crash (如果手机上没有安装处理某个scheme开头的url的APP, 会导致crash)
                    e.printStackTrace();
                    return true; //没有安装该app时，返回true，表示拦截自定义链接，但不跳转，避免弹出上面的错误页面
                }
                view.loadUrl(url);
                return true;
            }
        });
        //实现文件上传的接口
        final ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),result -> {
            if(result.getResultCode() == RESULT_OK){
                if(uploadFile != null){
                    final Uri _result = result.getData() == null ? null : result.getData().getData();
                    uploadFile.onReceiveValue(_result);
                    uploadFile = null;
                }
                if(uploadFiles != null){
                    final Uri _result = result.getData() == null ? null : result.getData().getData();
                    uploadFiles.onReceiveValue(new Uri[]{_result});
                    uploadFiles = null;
                }
            }else if(result.getResultCode() == RESULT_CANCELED){
                if(uploadFile != null){
                    uploadFile.onReceiveValue(null);
                    uploadFile = null;
                }
                if(uploadFiles != null){
                    uploadFiles.onReceiveValue(null);
                    uploadFiles = null;
                }
            }
        });
        webView.setWebChromeClient(new WebChromeClient(){
            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
                Log.d("网页","要上传文件啦！！");
                if(PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    Toast.makeText(MainActivity.this,"请授权后再进行文件上传！", Toast.LENGTH_SHORT).show();
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
                    return false; //不处理，忽略
                }else{ //已经有存储权限，可以上传文件
                    uploadFiles = filePathCallback;
                    final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.setType("*/*");
                    launcher.launch(Intent.createChooser(intent, "选择文件"));
                    return true; //要处理，并进行回调
                }
            }
        });
        CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true); //设置允许cookie
        webView.addJavascriptInterface(this, "android"); //注入JS接口函数
        webView.loadUrl(url_index);
    }

    @Override
    protected void onDestroy() {
        if(webView != null) {
            webView.destroy();
            webView = null;
        }
        super.onDestroy();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {  //加载菜单
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case R.id.clearCache: //清除缓存
                final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("清空缓存？");
                builder.setMessage(R.string.notice);
                builder.setCancelable(false); //不可取消
                builder.setNegativeButton("取消", (dialogInterface, i) -> dialogInterface.cancel());
                builder.setPositiveButton("确定", (dialogInterface, i) -> {
                    //清空历史缓存
                    webView.clearHistory();
                    webView.clearCache(true);
                    //清空Cookie
                    final CookieManager cookieManager = CookieManager.getInstance();
                    cookieManager.removeSessionCookies(null);
                    cookieManager.removeAllCookies(null);
                    cookieManager.flush();
                    //清空webView的LocalStorage
                    WebStorage.getInstance().deleteAllData();
                    Toast.makeText(this, "缓存已清空！", Toast.LENGTH_SHORT).show();
                    sharedPreferences.edit().remove("username").remove("password").apply();
                    startActivity(new Intent(this, LoginActivity.class));
                    finish();
                });
                builder.show();
                break;
            case R.id.goIndex: //回主页
                webView.clearHistory(); //清空返回栈（当前页面还是在的）
                webView.loadUrl(url_index);
                break;
            case R.id.checkUpdate: //检查更新
                new Thread(() -> {
                    try {
                        final Request request = new Request.Builder().url(url_update).get().build();
                        final OkHttpClient client = new OkHttpClient();
                        final Response response = client.newCall(request).execute();
                        final String[] res = response.body().string().split("\n");
                        Log.d("检查更新",res[0]);
                        Log.d("下载地址",res[1]);
                        if(Integer.parseInt(res[0].trim()) > VERSION){
                            runOnUiThread(() -> Toast.makeText(MainActivity.this,"发现新版本！",Toast.LENGTH_SHORT).show());
                            final Uri uri = Uri.parse(res[1]); //用系统浏览器打开下载地址
                            startActivity(new Intent(Intent.ACTION_VIEW, uri));
                        }else
                            runOnUiThread(() -> Toast.makeText(MainActivity.this,"当前已是最新版本！",Toast.LENGTH_SHORT).show());
                    }catch (Exception e){
                        e.printStackTrace();
                        runOnUiThread(() -> Toast.makeText(MainActivity.this, "网络连接失败！请检查网络！",Toast.LENGTH_SHORT).show());
                    }
                }).start();
                break;
            case R.id.fresh:  //刷新
                webView.reload();
                Toast.makeText(this, "正在刷新...", Toast.LENGTH_SHORT).show();
                break;
        }
        return true;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
            webView.goBack();  //设置按返回键时webview返回上一页
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @JavascriptInterface
    public void startLocation(){
        if(checkPermission()) { //权限检查通过
            Toast.makeText(this, "开始定位", Toast.LENGTH_SHORT).show();
            Log.d("startLocation", "开始定位");
            try {
                AMapLocationClient.updatePrivacyShow(this, true, true);
                AMapLocationClient.updatePrivacyAgree(this, true);
                final AMapLocationClient mLocationClient = new AMapLocationClient(this);
                mLocationClient.setLocationListener(aMapLocation -> {
                    if (aMapLocation != null && aMapLocation.getErrorCode() == 0) {
                        //省,城市,城区,街道,地址
                        final String place = aMapLocation.getProvince() + "," + aMapLocation.getCity() + ","
                                + aMapLocation.getDistrict() + "," + aMapLocation.getStreet() + "," + aMapLocation.getStreetNum();
                        final String coordinate = aMapLocation.getLongitude() + "," + aMapLocation.getLatitude();
                        Log.d("定位地点", place);
                        Log.d("定位坐标", coordinate);
                        try {
                            final JSONObject jSONObject = new JSONObject();
                            jSONObject.put("place", place); //"浙江省,杭州市,钱塘区,25号大街,159号"
                            jSONObject.put("coordinate", coordinate); //"120.380147,30.311694"
                            runOnUiThread(() -> webView.evaluateJavascript("javascript:getCurrentLocation('" + jSONObject.toString() + "')", null));
                        } catch (Exception ee) {
                            ee.printStackTrace();
                        }
                        mLocationClient.stopLocation();
                        mLocationClient.onDestroy();
                    }
                });
                final AMapLocationClientOption option = new AMapLocationClientOption();
                option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
                option.setOnceLocation(true); //仅定位一次
                mLocationClient.setLocationOption(option);
                mLocationClient.startLocation();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            Toast.makeText(this, "请先授权再进行晚打卡！", Toast.LENGTH_SHORT).show();
            ActivityCompat.requestPermissions(this, permissions, 1);
        }
    }

    private boolean checkPermission(){ //检查权限是否足够
        for(String s: permissions){
            if(PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, s))
                return false;
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        for (int grantResult : grantResults) {
            if (grantResult != PackageManager.PERMISSION_GRANTED) {
                if(requestCode == 1) //晚打卡
                        Toast.makeText(this, "权限不足，无法进行晚打卡！", Toast.LENGTH_LONG).show();
                else //上传附件
                        Toast.makeText(this, "权限不足，无法上传文件！", Toast.LENGTH_LONG).show();
                break;
            }
        }
    }
}